<?php
/**
 * Http 请求信息解析
 * */
namespace socket;

class HttpRequest
{
    protected $requestBodyBlock = '';

    protected $requestHeaderBlock = '';

    public $requestUrl = '';

    public $requestMethod = 'GET';

    public $httpVersion = '1.1';

    public $requestHeader = [];

    public $requestBody = '';

    public $requestQueryString = '';

    public $_GET = [];

    public $_POST = [];

    /**
     * @param   $requestBody
     * */
    public function __construct($requestBody)
    {
        $this->requestBodyBlock = $requestBody;
        $this->initRequestInfo();
    }

    /**
     * 解析请求头
     * */
    protected function initRequestInfo() {
        $info = explode("\r\n\r\n", $this->requestBodyBlock);
        $this->requestHeaderBlock = $info[0];
        if (isset($info[1])) {
            $this->requestBody = $info[1];
        } else {
            $this->requestBody = '';
        }
    }

    /**
     * 解析 GET 参数
     * */
    protected function parseParam() {
        $queryString = $this->requestQueryString;
        $arr = explode('&', $queryString);
        $params = [];
        foreach ($arr as $idx => $item){
            $tmp = explode('=', $item);
            if (isset($tmp[1])){
                $params[$tmp[0]] = $tmp[1];
            }
        }
        $this->_GET = $params;
    }

    /**
     * 解析请求信息
     * */
    public function parseInfo() {
        $headers = explode("\r\n", $this->requestHeaderBlock);
        $headerMap = [];
        foreach ($headers as $idx => $item){
            // 解析请求方式, Url, http 版本
            if (preg_match('/^(GET|POST|PUT|HEAD|DELETE)\s.*$/', $item)){
                preg_match('/^(GET|POST|PUT|HEAD|DELETE)\s([^\s]+)\sHTTP\/([^\s]+)[\s]*$/', $item, $matches);
                if (isset($matches[3])){
                    $this->requestMethod = trim($matches[1]);
                    $this->requestUrl = trim($matches[2]);
                    $this->httpVersion = trim($matches[3]);
                }
            } else {    // Http Header 解析
                preg_match('/^([A-z0-9-_+]+): (.*)$/', $item, $matches);
                if (isset($matches[1]) && isset($matches[2])){
                    $headerMap[trim($matches[1])] = trim($matches[2]);
                }
            }
        }

        // QueryString 处理
        $url = explode('?', $this->requestUrl);
        $this->requestUrl = $url[0];
        $this->requestQueryString = isset($url[1]) ? $url[1] : '';
        $this->parseParam();

        $this->requestHeader = $headerMap;
    }
}
